package net.butfly.albacore.dao.plugin;

import java.util.Map;

import net.butfly.albacore.criteria.Criteria;
import net.butfly.albacore.criteria.Page;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
		RowBounds.class, ResultHandler.class }) })
public class OraclePaginationPlugin extends PaginationBasePlugin {
	private final static String PAGE_PARTTERN = "select * from (select TMP_A__.*, rownum row_num__ from (%s) TMP_A__ ) TMP_B__ where TMP_B__.ROW_NUM__ between %s and %s";

	@SuppressWarnings("unchecked")
	@Override
	protected String paginationSql(String sql, Object args) {
		if (args instanceof Map) {
			Map<String, Object> map = ((Map<String, Object>) args);
			if (map.containsKey(Criteria.PAGE_PROPERTY)) {
				Page page = (Page) map.get(Criteria.PAGE_PROPERTY);
				sql = String.format(PAGE_PARTTERN, sql, page.getStart() + 1, page.getStart() + page.getSize());
			} else if (map.containsKey("rowBounds")) {
				RowBounds rb = (RowBounds) map.get("rowBounds");
				sql = String.format(PAGE_PARTTERN, sql, rb.getOffset() + 1, rb.getOffset() + rb.getLimit());
			}
		}
		return sql;
	}
}